home *** CD-ROM | disk | FTP | other *** search
/ Aminet 4 / Aminet 4 - November 1994.iso / aminet / dev / c / cweb31p9d.lha / CWeb / examples / cct.w next >
Text File  |  1994-07-09  |  6KB  |  181 lines

  1. \def\fin{\par\vfill\eject % this is done when we are ending the index
  2.   \message{Section names:}
  3.   \def\note##1##2.{\quad{\eightrm##1~##2.}}
  4.   \def\U{\note{Used in section}} % crossref for use of a section
  5.   \def\Us{\note{Used in sections}} % crossref for uses of a section
  6.   \def\I{\par\hangindent 2em}\let\*=*
  7.   \readsections}
  8.  
  9. \nocon
  10.  
  11. @* Character code translation.  It is a non-trivial task to transfer `text
  12. files' from one computer system to another, because of the different code
  13. tables in use.  For example, on the Amiga there is {\mc ECMA}~94, also known
  14. as {\mc ISO}~Latin~1 or {\mc ISO}~8859-1, {\mc MSDOS} has {\mc IBM}'s
  15. International CodePage~850, and on some \UNIX/ systems there is {\mc
  16. HP}~8.  All of these code tables are extensions to the standard {\mc
  17. ASCII}, i.e., they provide additional symbols and characters with codes
  18. from~128 to~255.  The following program is a simple tool for file
  19. conversion by means of external translation files.
  20.  
  21. @c
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. @#
  26. void main(int argc, char **argv)
  27.    {
  28.    @<Local variables of |main|@>@;
  29. @#
  30.    @<Initialize the local variables@>@;
  31.    @<Scan the arguments from the command line@>@;
  32.    @<Set up the translation tables for both directions@>@;
  33.    @<Copy |in_file| to |out_file| according to |trans_file|@>@;
  34.    @<The endgame@>@;
  35.    }
  36.  
  37. @ There are three different files used in the process of code translation.
  38. Input is read from |in_file| and written to |out_file|.  |trans_file| is a
  39. special file with exactly 512~characters in two groups of 256~characters
  40. each, defining two translation tables at once.
  41.  
  42. @d in_file file[0]
  43. @d out_file file[1]
  44. @d trans_file file[2]
  45. @#
  46. @d in_file_name file_name[0]
  47. @d out_file_name file_name[1]
  48. @d trans_file_name file_name[2]
  49. @d prog_name file_name[3]
  50.  
  51. @<Local variables of |main|@>=
  52. FILE *file[3];
  53. char file_name[4][60];
  54.  
  55. @ To control the direction of translation, this program accepts two
  56. command line options, indicated by a leading `\.-' sign.  If you set
  57. `\.{-t}' anywhere in the command line, translation is done according to
  58. the |to_code| table, i.e., the output is written by means of this table.
  59. If you set `\.{-f}', all characters read from |in_file| are translated
  60. according to the |from_code| table.  You shouldn't use `\.{-f}' and
  61. `\.{-t}' simultaneously.
  62.  
  63. @d copy_from flags['f']
  64. @d copy_to flags['t']
  65.  
  66. @<Local variables of |main|@>=
  67. unsigned char uc,*cp,from_code[256],to_code[256],flags[256];
  68. unsigned char found_trans,found_in,found_out;
  69. int i;
  70.  
  71. @ Either we use global variables, which are statically zeroed, or we must
  72. do this ourselves.
  73.  
  74. @<Initialize the local variables@>=
  75.    strcpy(prog_name,argv[0]);
  76.    for(i=0; i<256; i++)
  77.       flags[i]=0;
  78.    found_trans=found_in=found_out=0;
  79.  
  80. @ @<Scan the arguments from the command line@>=
  81.    while(--argc>0) {
  82.       if(**(++argv)=='-')
  83.          @<Handle flag argument@>@;
  84.       else {
  85.          if(!found_trans)
  86.             @<Make |trans_file_name| and open |trans_file|@>@;
  87.          else if(!found_in)
  88.             @<Make |in_file_name| and open |in_file|@>@;
  89.          else if(!found_out)
  90.             @<Make |out_file_name| and open |out_file|@>@;
  91.          }
  92.       }
  93.    if(!found_in || !found_out || !found_trans) {
  94.       fprintf(stderr,"Usage: %s [options] trans_file in_file out_file\n"@|
  95.          "\toptions are\n"@|
  96.          "\t\t-t to translate to another codepage\n"@|
  97.          "\t\t-f to translate from another codepage\n",prog_name);
  98.       exit(1);
  99.       }
  100.  
  101. @ There is a flag value for each possible character code, although only two
  102. of them have a sensible meaning.
  103.  
  104. @<Handle flag argument@>=
  105.    for(cp=*argv+1; *cp>'\0'; cp++)
  106.       flags[*cp]=1;
  107.  
  108. @ @<Make |trans_file_name| and open |trans_file|@>={
  109.    strcpy(trans_file_name,*argv);
  110.    if(!(trans_file=fopen(trans_file_name,"r"))) exit(1);
  111.    found_trans=1;
  112.    }
  113.  
  114. @ @<Make |in_file_name| and open |in_file|@>={
  115.    strcpy(in_file_name,*argv);
  116.    if(!(in_file=fopen(in_file_name,"r"))) exit(1);
  117.    found_in=1;
  118.    }
  119.  
  120. @ @<Make |out_file_name| and open |out_file|@>={
  121.    strcpy(out_file_name,*argv);
  122.    if(!(out_file=fopen(out_file_name,"w"))) exit(1);
  123.    found_out=1;
  124.    }
  125.  
  126. @ After the files have been opened, the translation tables can be read
  127. from |trans_file|.  Here we don't check for errors in |trans_file|.
  128. Make sure that there are at least 512~characters to read.  The first
  129. half of |trans_file| gives the translation rules for conversion ``from
  130. the home system to the target system,'' i.e., for every character position
  131. from~0 to~255 the numeric equivalent for the target system is given in form
  132. of a byte value, the second half is the other way round, i.e., for every
  133. character value from the foreign system the equivalent of the home system
  134. is defined.  As soon this is done, we close the translation file.
  135.  
  136. @<Set up the translation tables for both directions@>=
  137.    for(i=0; i<256; i++)
  138.       to_code[i] = (unsigned char)fgetc(trans_file);
  139.    for(i=0; i<256; i++)
  140.       from_code[i] = (unsigned char)fgetc(trans_file);
  141.  
  142.    fclose(trans_file);
  143.  
  144. @ The code in this section actually translates |in_file| to |out_file|
  145. according to the rules given in |trans_file|.  Here are two examples:
  146.  
  147. If you want to translate one of your {\mc ASCII} files for use on another
  148. system, e.g., from Amiga to {\mc MSDOS}, use something like
  149.  
  150. \.{ct pc850.crossdos {\it$\langle$Amiga file$\rangle$}
  151. -t {\it$\langle$MSDOS file$\rangle$}}
  152.  
  153. If you want to translate a file from another system to make it usable on
  154. your own system, e.g., from {\mc MSDOS} to Amiga, use something like
  155.  
  156. \.{ct pc850.crossdos -f {\it$\langle$MSDOS file$\rangle$
  157. $\langle$Amiga file$\rangle$}}
  158.  
  159. Note that in both cases \.{pc850.crossdos} is used as the |trans_file|, but
  160. the direction of translation is determined by the appropriate option.  There
  161. is no sense in setting both the `\.{-f}' and the `\.{-t}' option, the
  162. results would get fouled up.
  163.  
  164. @<Copy |in_file| to |out_file| according to |trans_file|@>=
  165.    while((uc = (unsigned char)fgetc(in_file)) != EOF) {
  166.       if(copy_from) uc = from_code[uc];
  167.       if(copy_to)
  168.          fputc((int)to_code[uc],out_file);
  169.       else
  170.          fputc((int)uc,out_file);
  171.       }
  172.  
  173. @ After our work is done we close the source and the target files and quit.
  174.  
  175. @<The endgame@>=
  176.    fclose(in_file);
  177.    fclose(out_file);
  178.    exit(0);
  179.  
  180. @* Index.
  181.